﻿using System.Globalization;
using System.Text;
using System.Web;
using System.Web.UI;

namespace Eksponent.CropUp.Client
{
    public static class CropUpHtml
    {
        private static CultureInfo jsCulture = CultureInfo.GetCultureInfo("en-US");

        /// <summary>
        /// If you have manually included CropUp.js to avoid inline script tags set this to true somewhere (preferably App_Startup)
        /// </summary>
        public static bool CropUpScriptIncluded { get; set; }

        /// <summary>
        /// The url to cropup.js (defaults to ~/Scripts/CropUp.js)
        /// </summary>
        public static string CropUpScript { get; set; }

        /// <summary>
        /// The url to cropup.js (defaults to ~/Scripts/CropUp.Editor.js)
        /// </summary>
        public static string CropUpEditorScript { get; set; }


        static CropUpHtml()
        {
            CropUpScript = "~/Scripts/CropUp.js";
            CropUpEditorScript = "~/Scripts/CropUp.Editor.js";
        }


        /// <summary>
        /// Returns a path to the image given it's relative path and the arguments specified.
        /// </summary>
        /// <param name="imageRelPath">The image's relative path.</param>
        /// <param name="arguments">The arguments controlling how to present the image.</param>
        /// <returns></returns>
        public static string CropUp(string imageRelPath, ImageSizeArguments arguments = null)
        {           
            return Eksponent.CropUp.CropUp.GetUrl(imageRelPath, arguments);
        }

        /// <summary>
        /// Generates the markup required to use CropUp on the image client side.
        /// If both width and height are omitted responsive adaption will be used. In that case a positive value for upscaleStep (e.g. 200) will look cooler, but upscaleStep = 0 saves bandwidth.
        /// </summary>
        /// <param name="imageRelPath">The image's relative path.</param>
        /// <param name="width">The width of the server side generated image.</param>
        /// <param name="height">The height of the server side generated image.</param>
        /// <param name="cropAlias">Specify to use the pre-defined cropping with that alias. (null=Default will do in most cases)</param>
        /// <param name="zoom">if set to <c>true</c> the image is allowed to upscale client side.</param>
        /// <param name="style">Optional value for the div generated's style attribute.</param>
        /// <param name="cssClass">Optional extra CSS classes to add to the div generated.</param>
        /// <param name="id">Optional id for the div element generated.</param>
        /// <param name="upscaleStep">The step size to progressively increase image size if width and height are omitted. If zero server side cropping will be used for responsive adaption</param>
        /// <param name="cropInfo">Optional crop info to override the data from the provider.</param>
        /// <returns></returns>
        public static HtmlString CropUpResponsive(string imageRelPath, int? width = null, int? height = null,
            string cropAlias = null,
            bool zoom = true,
            string style = null, string cssClass = null, string id = null, int upscaleStep = 0, CropInfo cropInfo = null)
        {
            var sb = new StringBuilder();

            if( !CropUpScriptIncluded && !true.Equals(HttpContext.Current.Items["CropUpScriptIncluded"]))
            {
                HttpContext.Current.Items["CropUpScriptIncluded"] = true;

                sb.Append("<script type=\"text/javascript\" src=\"");
                sb.Append(VirtualPathUtility.ToAbsolute(CropUpScript));
                sb.Append("\"></script>");
            }


            if (!imageRelPath.StartsWith("~")) imageRelPath = "~" + imageRelPath;

            var data = Eksponent.CropUp.CropUp.CropDataProvider.GetCropData(imageRelPath);            
            sb.Append("<div ");
            if (!string.IsNullOrEmpty(id)) sb.Append("id=\"").Append(id).Append("\" ");
            if (!string.IsNullOrEmpty(style)) sb.Append("style=\"").Append(HttpUtility.HtmlEncode(style)).Append("\" ");
            sb.Append("class=\"crop-up");
            if (!string.IsNullOrEmpty(cssClass)) sb.Append(" ").Append(cssClass);
            sb.Append("\" ");
            if (data != null || cropInfo != null)
            {
                CropInfo info;
                if (string.IsNullOrEmpty(cropAlias) || !data.ManualCroppings.TryGetValue(cropAlias, out info))
                {
                    info = cropInfo ?? data.Default;
                }

                
                if (info.Gravity.HasValue)
                {
                    sb.AppendFormat(jsCulture, "data-gravity=\"{0},{1}\" ", info.Gravity.Value.X, info.Gravity.Value.Y);
                }

                sb.AppendFormat(jsCulture, "data-box=\"{0},{1},{2},{3}\" ", info.TopLeft.X, info.TopLeft.Y, info.BottomRight.X, info.BottomRight.Y);
            }

            //var size = Eksponent.CropUp.CropUp.Dialect.GetImageSize(imageRelPath);
            //sb.Append("data-original-size=\"").Append(size.Width).Append(",").Append(size.Height).Append("\" ");

            if (zoom) sb.Append("data-zoom=\"true\" ");

            if (!width.HasValue && !height.HasValue)
            {
                sb.Append("data-upscale-url=\"")
                    .Append(Eksponent.CropUp.CropUp.Dialect.GetResponsiveUrl(imageRelPath, upscaleStep > 0, zoom))
                    .Append("\" data-upscale-step=\"").Append(upscaleStep).Append("\" ");                
            }
            else
            {
                sb.Append("data-image=\"").Append(Eksponent.CropUp.CropUp.Dialect.GetUrl(imageRelPath,
                    new ImageSizeArguments
                        {
                            Width = width,
                            Height = height,
                            CropMode = CropUpMode.Responsive
                        })).Append("\"");
            }
            
            sb.Append("></div>");

            return new HtmlString(sb.ToString());
        }
    }
}
